#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <gmp.h>

/* No. de pontos testados no programa */
unsigned long POINTS = 0;

int main(int argc, char *argv[])
{
	long double pi;

	int n, m;
	int i;
	long double x, y;
	mpf_t l_pi, l_m, l_n;

    if(argc != 2)
    {
        printf("Erro: número de parametros invalido!\n");
        return -1;
    }
    else
    {
    	POINTS = atoi(argv[1]);
        /* Inicialização de variáveis*/
        n = m = 0;
        srand(time(NULL));
        mpf_init(l_pi);
        mpf_init(l_m);
        mpf_init(l_n);

        int DIGITS = 10000000;
        /* Ajuste da precisão */
        mpf_set_default_prec(3.33 * DIGITS);

        /* Geração de pontos para a fórmula*/
        for(i = 0; i < POINTS; i++)
        {
            /* Geração de valores aleatórios para os pontos */
            x = rand();
            y = rand();
            x /= RAND_MAX;
            y /= RAND_MAX;
            /* Testa se o ponto está no círculo. Se sim, incrementa m */
            if((x*x+y*y) < 1)
                m++;

            n++;
        }

        /* Cálculo da fórmula */
        mpf_set_d(l_pi, 4.0f);
        mpf_mul_ui(l_pi, l_pi, m);
        mpf_div_ui(l_pi, l_pi, n);

        /* Saída do resultado */
        mpf_out_str(NULL, 10, DIGITS, l_pi);
        printf("\n");

        /* Cálculo utilizando long double */
        pi = (long double)4.0f*m/n;
        /* Saída de long double */
        printf("pi = %llf\n", pi);

        /* Limpeza de memória */
        mpf_clear(l_pi);
        mpf_clear(l_m);
        mpf_clear(l_n);

        return 0;
    }
}
